{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# [Java中volatile关键字详解](https://www.cnblogs.com/zhengbin/p/5654805.html)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 基本概念\n",
    "**先补充一下概念：Java 内存模型中的`可见性`、`原子性`和`有序性`。**\n",
    "\n",
    "**可见性：可见性，是指线程之间的可见性，一个线程修改的状态对另一个线程是可见的。**\n",
    "\n",
    "也就是一个线程修改的结果。另一个线程马上就能看到。比如：用`volatile修饰`的变量，就会具有可见性。volatile修饰的变量不允许线程内部缓存和重排序，即直接修改内存。所以对其他线程是可见的。但是这里需要注意一个问题，volatile只能让被他修饰内容具有可见性，但不能保证它具有原子性。比如 volatile int a = 0；之后有一个操作 a++；这个变量a具有可见性，但是a++ 依然是一个非原子操作，也就是这个操作同样存在线程安全问题。\n",
    "\n",
    "可见性是一种复杂的属性，因为可见性中的错误总是会违背我们的直觉。通常，我们无法确保执行读操作的线程能适时地看到其他线程写入的值，有时甚至是根本不可能的事情。为了确保多个线程之间对内存写入操作的可见性，必须使用同步机制。\n",
    "\n",
    "**在 Java 中 volatile、synchronized 和 final 实现可见性。**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**原子性：原子是世界上的最小单位，具有不可分割性。一个操作是原子操作，那么我们称它具有原子性。**\n",
    "\n",
    "比如 a=0；（a非long和double类型） 这个操作是不可分割的，那么我们说这个操作时原子操作。再比如：a++； 这个操作实际是a = a + 1；是可分割的，所以他不是一个原子操作。非原子操作都会存在线程安全问题，需要我们使用同步技术（sychronized）来让它变成一个原子操作。一个操作是原子操作，那么我们称它具有原子性。java的concurrent包下提供了一些原子类，我们可以通过阅读API来了解这些原子类的用法。比如：AtomicInteger、AtomicLong、AtomicReference等。\n",
    "\n",
    "**在 Java 中 synchronized 和在 lock、unlock 中操作保证原子性。**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**有序性：**\n",
    "\n",
    "Java 语言提供了 volatile 和 synchronized 两个关键字来保证线程之间操作的有序性，volatile 是因为其本身包含“禁止指令重排序”的语义，synchronized 是由“一个变量在同一个时刻只允许一条线程对其进行 lock 操作”这条规则获得的，此规则决定了持有同一个对象锁的两个同步块只能串行执行。\n",
    "\n",
    "**下面内容摘录自《Java Concurrency in Practice》：**\n",
    "\n",
    "下面一段代码在多线程环境下，将存在问题。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "public class NoVisibility {\n",
    "     private static boolean ready;\n",
    "     private static int number;\n",
    "     private static class ReaderThread extends Thread {\n",
    "         @Override\n",
    "         public void run() {\n",
    "             while(!ready) {\n",
    "                 Thread.yield();\n",
    "             }\n",
    "             System.out.println(number);\n",
    "         }\n",
    "     }\n",
    "     public static void main(String[] args) {\n",
    "         new ReaderThread().start();\n",
    "         number = 42;\n",
    "         ready = true;\n",
    "     }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　NoVisibility可能会持续循环下去，因为读线程可能永远都看不到ready的值。甚至NoVisibility可能会输出0，因为读线程可能看到了写入ready的值，但却没有看到之后写入number的值，这种现象被称为“重排序”。只要在某个线程中无法检测到重排序情况（即使在其他线程中可以明显地看到该线程中的重排序），那么就无法确保线程中的操作将按照程序中指定的顺序来执行。当主线程首先写入number，然后在没有同步的情况下写入ready，那么读线程看到的顺序可能与写入的顺序完全相反。\n",
    "\n",
    "　　在没有同步的情况下，编译器、处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整。在缺乏足够同步的多线程程序中，要想对内存操作的执行春旭进行判断，无法得到正确的结论。\n",
    "\n",
    "　　这个看上去像是一个失败的设计，但却能使JVM充分地利用现代多核处理器的强大性能。例如，在缺少同步的情况下，Java内存模型允许编译器对操作顺序进行重排序，并将数值缓存在寄存器中。此外，它还允许CPU对操作顺序进行重排序，并将数值缓存在处理器特定的缓存中。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 补充：重排序\n",
    "#### 什么是重排序？\n",
    "执行任务的时候，为了提高编译器和处理器的执行性能，编译器和处理器(包括内存系统，内存在行为没有重排但是存储的时候是有变化的)会对指令重排序。编译器优化的重排序是在编译时期完成的，指令重排序和内存重排序是处理器重排序\n",
    "\n",
    "1. 编译器优化的重排序，在不改变单线程语义的情况下重新安排语句的执行顺序\n",
    "2. 指指令级并行重排序，处理器的指令级并行技术将多条指令重叠执行，如果不存在数据的依赖性将会改变语句对应机器指令的执行顺序\n",
    "3. 内存系统的重排序，因为使用了读写缓存区，使得看起来并不是顺序执行的\n",
    "\n",
    "#### 重排序会产生什么问题\n",
    "1. 重排序可能会导致多线程程序出现内存可见性问题。(工作内存和主内存，编译器处理器重排序导致的可见性）\n",
    "2. 重排序会导致有序性问题，程序的读写顺序于内存的读写顺序不一样（编译器处理器重排序，内存缓冲区(是处理器重排序的内容))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### happen-before\n",
    "java内存模型中提供的happens-before辅助保证程序执行的原子性可见性和有序性的问题，是判断线程是否存在竞争，线程是否安全的依据\n",
    "\n",
    "java内存模型提供了8种happen-before规则，帮助实现原子性可见性和有序性，**在执行程序的时候查看是否满足happen-before的8种规则，如果满足的话就能够保证线程安全**\n",
    "\n",
    "1. **程序顺序原则**：一个线程内要按照代码的顺序执行，保证语义的串行性\n",
    "2. **锁规则**：解锁操作必须发生在对同一个锁的加锁操作之前\n",
    "3. **volatile规则**：对volatile修饰的变量的写操作发生在volatile变量的读操作之前。访问volatile的变量时候强制从主内存中进行读取，volatile修饰的变量被修改之后会被强制的刷新到主内存中。所以说volatile修饰的变量保证了可见性\n",
    "4. **线程启动规则**：线程的start()方法最先执行，线程A在线程B执行start()方法之前对共享变量的修改对线程B可见\n",
    "5. **线程终止规则**：线程的所有操作优于线程的终结，Thread.join()方法的作用是等待当前线程终止，线程B在终止之前修改了共享变量，执行完成后，线程B对共享变量的修改将对线程A可见\n",
    "6. **线程中断规则**：对线程interrupt中断方法的调用发生在被中断的线程检测到中断事件的发生之前\n",
    "7. **对象终结规则**：对象的构造函数执行完成先于finalize()方法\n",
    "8. **传递性**：线程A生在线程B之前，线程B发生在线程C之前，则线程A发生在线程C之前"
   ]
  },
  {
   "attachments": {
    "image.png": {
     "image/png": "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"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## volatile原理\n",
    "　　Java语言提供了一种稍弱的同步机制，即**volatile变量，用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后，编译器与运行时都会注意到这个变量是共享的，因此不会将该变量上的操作与其他内存操作一起重排序**。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方，因此在读取volatile类型的变量时总会返回最新写入的值。\n",
    "　　**<p style=\"color:red\">在访问volatile变量时不会执行加锁操作，因此也就不会使执行线程阻塞，因此volatile变量是一种比sychronized关键字更轻量级的同步机制。</p>**\n",
    "\n",
    "![image.png](attachment:image.png)\n",
    "    当对非 volatile 变量进行读写的时候，每个线程先从内存拷贝变量到CPU缓存中。如果计算机有多个CPU，每个线程可能在不同的CPU上被处理，这意味着每个线程可以拷贝到不同的 CPU cache 中。\n",
    "　　**<p style=\"color:red\">而声明变量是 volatile 的，JVM 保证了每次读变量都从内存中读，跳过 CPU cache 这一步。</p>**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 特性\n",
    "**当一个变量定义为 volatile 之后，将具备两种特性：**\n",
    "1. 保证此变量对所有的线程的可见性，这里的“可见性”，如本文开头所述，当一个线程修改了这个变量的值，volatile 保证了新值能立即同步到主内存，以及每次使用前立即从主内存刷新。但普通变量做不到这点，普通变量的值在线程间传递均需要通过主内存（详见：[Java内存模型](https://www.cnblogs.com/zhengbin/p/6407137.html)）来完成。\n",
    "\n",
    "2. 禁止指令重排序优化。有volatile修饰的变量，赋值后多执行了一个“load addl $0x0, (%esp)”操作，这个操作相当于一个内存屏障（指令重排序时不能把后面的指令重排序到内存屏障之前的位置），只有一个CPU访问内存时，并不需要内存屏障；（什么是指令重排序：是指CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 性能\n",
    "volatile 的读性能消耗与普通变量几乎相同，但是写操作稍慢，因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Java",
   "language": "java",
   "name": "java"
  },
  "language_info": {
   "codemirror_mode": "java",
   "file_extension": ".jshell",
   "mimetype": "text/x-java-source",
   "name": "Java",
   "pygments_lexer": "java",
   "version": "11.0.8+10-post-Ubuntu-0ubuntu120.04"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
